home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 424_01 / ed_157 / nntp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-21  |  6.7 KB  |  286 lines

  1. /*
  2.  * Copyright (C) 1992 by Rush Record
  3.  * Copyright (C) 1993 by Charles Sandmann (sandmann@clio.rice.edu)
  4.  * 
  5.  * This file is part of ED.
  6.  * 
  7.  * ED is free software; you can redistribute it and/or modify it under the terms
  8.  * of the GNU General Public License as published by the Free Software Foundation.
  9.  * 
  10.  * ED is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  11.  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  12.  * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  13.  * 
  14.  * You should have received a copy of the GNU General Public License along with ED
  15.  * (see the file COPYING).  If not, write to the Free Software Foundation, 675
  16.  * Mass Ave, Cambridge, MA 02139, USA.
  17.  */
  18. #include "opsys.h"
  19.  
  20. #ifndef NO_NEWS
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <errno.h>
  26.  
  27. #ifdef VMS
  28.  
  29. #ifdef MULTINET
  30. #include "multinet_root:[multinet.include.sys]types.h"
  31. #include "multinet_root:[multinet.include.sys]socket.h"
  32. #include "multinet_root:[multinet.include.netinet]in.h"
  33. #include "multinet_root:[multinet.include]netdb.h"
  34. #define read socket_read
  35. #define write socket_write
  36. #define close socket_close
  37. #endif
  38.  
  39. #ifdef WOLLONGONG
  40. #include <in.h>
  41. #include <netdb.h>
  42. #include <socket.h>
  43. #include <inet.h>
  44. #define read netread
  45. #define write netwrite
  46. #define close netclose
  47. #endif
  48.  
  49. #ifdef UCX
  50. #include <in.h>
  51. #include <netdb.h>
  52. #include <socket.h>
  53. #include <inet.h>
  54. #endif
  55.  
  56. #else
  57.  
  58. #include <setjmp.h>
  59. #include <netdb.h>
  60. #include <sys/file.h>
  61. #include <sys/stat.h>
  62. #include <sys/socket.h>
  63. #include <sys/types.h>
  64. #include <arpa/inet.h>
  65. #include <netinet/in.h>
  66.  
  67. #endif
  68.  
  69. static Int inputchan = 0,outputchan = 0,controls;
  70. static FILE *inputfp = NULL;
  71. static struct sockaddr_in controlsocket;
  72. static struct hostent *host_info_ptr;
  73. static struct servent *svc_info;
  74. static short port;
  75. static Int posting_ok = 0;
  76. #ifdef DEBUG
  77. static FILE *dfp;
  78. #endif
  79.  
  80. /******************************************************************************\
  81. |Routine: posting_allowed
  82. |Callby: edit
  83. |Purpose: Returns 1 if posting is allowed, else 0.
  84. |Arguments:
  85. |    none
  86. \******************************************************************************/
  87. Int posting_allowed()
  88. {
  89.     return(posting_ok);
  90. }
  91.  
  92. /******************************************************************************\
  93. |Routine: news_close
  94. |Callby: news_open
  95. |Purpose: Closes connection to news server.
  96. |Arguments:
  97. |    none
  98. \******************************************************************************/
  99. void news_close()
  100. {
  101.     if(inputchan)
  102.     {
  103.         close(inputchan);
  104. /*        fclose(inputfp);*/
  105.         inputchan = 0;
  106.     }
  107.     if(outputchan)
  108.     {
  109.         close(outputchan);
  110.         outputchan = 0;
  111.     }
  112.     if(controls)
  113.     {
  114.         close(controls);
  115.         controls = 0;
  116.     }
  117. }
  118.  
  119. /******************************************************************************\
  120. |Routine: news_command
  121. |Callby: load_news
  122. |Purpose: Sends a command to the news server. Returns 0 if error, else 1.
  123. |Arguments:
  124. |    buf is a string containing the command.
  125. \******************************************************************************/
  126. Int news_command(buf)
  127. Char *buf;
  128. {
  129.     static Char *term = "\r\n";
  130.     
  131.     if(!outputchan)
  132.         return(0);
  133. #ifdef DEBUG
  134.     if(!dfp)
  135.         dfp = fopen("nntp.dat","w");
  136.     fprintf(dfp,"send:%s\n",buf);
  137.     fflush(dfp);
  138. #endif
  139.     if(write(outputchan,buf,strlen(buf)) != strlen(buf))
  140.         return(0);
  141.     if(write(outputchan,term,strlen(term)) != strlen(term))
  142.         return(0);
  143.     return(1);
  144. }
  145.  
  146. /******************************************************************************\
  147. |Routine: news_response
  148. |Callby: load_news news_open
  149. |Purpose: Reads a response from the news server. Returns the length of the
  150. |         response, or -1 if the connection wasn't open.
  151. |Arguments:
  152. |    buf is the buffer to store the response in.
  153. |    size is the size of buf.
  154. \******************************************************************************/
  155. Int news_response(buf,size)
  156. Char *buf;
  157. Int size;
  158. {
  159. #ifdef VMS
  160.     static Int cur = 0,remain = 0;
  161.     static Char vbuf[512];
  162.     Int bufptr;
  163. #endif
  164.     
  165.     buf[0] = '\0';
  166.     if(!inputchan)
  167.         return(-1);
  168. #ifdef VMS
  169.     bufptr = 0;
  170. again:
  171.     if(!remain)
  172.     {
  173.         while(!remain)
  174.             remain = read(inputchan,vbuf,sizeof(vbuf));
  175.         cur = 0;
  176.     }
  177.     while(remain--)
  178.     {
  179.         if((buf[bufptr++] = vbuf[cur++]) == '\n')
  180.         {
  181.             buf[bufptr - 2] = '\0';
  182.             return(strlen(buf));
  183.         }
  184.     }
  185.     remain = 0;
  186.     goto again;
  187. #else
  188.     fgets(buf,size,inputfp);
  189.     *(strchr(buf,'\r')) = '\0';
  190. #ifdef DEBUG
  191.     if(!dfp)
  192.         dfp = fopen("nntp.dat","w");
  193.     fprintf(dfp,"response:%s\n",buf);
  194.     fflush(dfp);
  195. #endif
  196. #endif    /* VMS */
  197.     return(strlen(buf));
  198. }
  199.  
  200. /******************************************************************************\
  201. |Routine: news_open
  202. |Callby: load_news
  203. |Purpose: Opens a connection to the news server. Returns 0 for error, else 1.
  204. |Arguments:
  205. |    server is the name of the news server.
  206. |    title is the server's connect greeting, which becomes the window title.
  207. |    size is the size of title.
  208. \******************************************************************************/
  209. Int news_open(server,title,size)
  210. Char *server,*title;
  211. Int size;
  212. {
  213.     Char buf[512],*from,*to;
  214.     Int i;
  215.  
  216.     news_close();
  217. /* get host info */
  218.     if(!(host_info_ptr = gethostbyname(server)))
  219.     {
  220.         sprintf(buf,"Unknown news server: %s",server);
  221.         slip_message(buf);
  222.         goto abort;
  223.     }
  224. /* get info about service (this should be called only once) */
  225.     if(!port)
  226.     {
  227. #ifdef _AIX
  228.         port = htons(119);
  229. #else
  230. #ifdef UCX
  231.         if((svc_info = getservbyname("nntp","tcp")) == (struct servent *)(-1))
  232. #else
  233.         if(!(svc_info = getservbyname("nntp","tcp")))
  234. #endif
  235.             port = htons(119);    /* use port 119 if getservbyname fails */
  236.         else
  237.             port = svc_info->s_port;
  238. #endif
  239.     }
  240.     memset(&controlsocket,0,sizeof(controlsocket));
  241.     memcpy((char *)&controlsocket.sin_addr,host_info_ptr->h_addr,host_info_ptr->h_length);
  242.     controlsocket.sin_family = host_info_ptr->h_addrtype;
  243.     controlsocket.sin_port = port;
  244. /* create control path */
  245.     if((controls = socket(host_info_ptr->h_addrtype,SOCK_STREAM,0)) < 0)
  246.     {
  247.         slip_message("Error creating socket for control path.");
  248.         goto abort;
  249.     }
  250. loop:
  251.     if(connect(controls,(struct sockaddr *)&controlsocket,sizeof(controlsocket))== -1)
  252.     {
  253.         if(errno == EINTR)
  254.             goto loop;
  255.         slip_message("Control connection failed.");
  256.         goto abort;
  257.     }
  258.     i = sizeof(controlsocket);
  259.     if(getsockname(controls,(struct sockaddr *)&controlsocket,&i) < 0)
  260.     {
  261.         slip_message("Couldn't get control socket name.");
  262.         goto abort;
  263.     }
  264.     inputchan = controls;
  265.     inputfp = fdopen(inputchan,"r");
  266.     outputchan = dup(controls);
  267.     news_response(title,size);    /* get the greeting, make it the buffer title */
  268.     if(title[0] != '2')
  269.     {
  270.         slip_message(title);
  271.         goto abort;
  272.     }
  273.     if(title[2] == '0')
  274.         posting_ok = 1;
  275.     else
  276.         posting_ok = 0;
  277.     for(from = title + 4,to = title;(*to++ = *from++););    /* shift out the response code */
  278.     return(1);
  279. abort:
  280.     wait_message();
  281.     news_close();
  282.     return(0);
  283. }
  284. #endif
  285.  
  286.